package com.gsoe.auth.config;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.json.JSONObject;
import com.gsoe.base.exception.UserException;
import com.gsoe.base.model.User;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.Data;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;

@Component
@ServerEndpoint("/connect/{sid}/{token}")

public class WebSocketServer {

    @Data
    public static class WebSocket{
        Session session;
        User user;
    }


    //存放会话对象
    private static final Map<String, WebSocket> sessionMap = new HashMap<>();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid, @PathParam("token") String token) {
        System.out.println("客户端：" + sid + "建立连接");
        User loginUser=null;
        try {
            JSONObject info = (JSONObject) StpUtil.getExtra(token, "info");
            loginUser=info.toBean(User.class);
        }catch (Exception e){
            throw new UserException("token无效");
        }

        WebSocket webSocket=new WebSocket();
        webSocket.session=session;
        webSocket.user=loginUser;

        sessionMap.put(sid, webSocket);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, @PathParam("sid") String sid) {
        System.out.println("收到来自客户端：" + sid + "的信息:" + message);
    }

    /**
     * 连接关闭调用的方法
     *
     * @param sid
     */
    @OnClose
    public void onClose(@PathParam("sid") String sid) {
        System.out.println("连接断开:" + sid);
        sessionMap.remove(sid);
    }

    /**
     * 群发
     *
     * @param message
     */
    public void sendToAllClient(String message, Predicate<WebSocket> filter) {
        Collection<WebSocket> sessions = sessionMap.values();

        List<WebSocket> webSockets = sessions.stream().filter(filter).toList();


        for (WebSocket webSocket : webSockets) {
            try {
                //服务器向客户端发送消息
                webSocket.session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}